class Suan {
    // 某个值是否连续某个次数出现
    /**
     * 
     * @param {棋盘数组} mapInfo 
     * @param {棋子种类 |0空|1电脑|2玩家} ps 
     * @param {连续出现次数} numCount 
     * @returns 连续出现的棋子位置数组 | false
     */
    isConsecutive(mapInfo, ps, numCount) {
        
        //连线数组
        let succArr = [];

        for (let i = 0; i < mapInfo.length; i++) {
            var num = 0;
            //横线判断
            for (let j = 0; j < mapInfo[i].length; j++) {
                if (mapInfo[i][j] != ps) {
                    num = 0;
                    succArr = [];
                } else {
                    num++;
                    succArr.push({
                        x:i,y:j
                    });
                }
                if (num == numCount) {
                    return succArr;
                }
            }
            num = 0;
            //竖线判断
            for (let j = 0; j < mapInfo[i].length; j++) {
                if (mapInfo[j][i] != ps) {
                    num = 0;
                    succArr = []
                } else {
                    num++;
                    succArr.push({
                        x:j,y:i
                    })
                }
                if (num == numCount) {
                    return succArr
                }
            }

            num = 0;
            //斜线判断

            for (let j = 0; j <= i; j++) {
                if (mapInfo[j][i - j] == ps) {
                    num++;
                    succArr.push({x:j,y:i-j});
                } else {
                    num = 0;
                    succArr = [];
                }
                if (num == numCount) {
                    return succArr
                }
            }

            num = 0;
            for (let j = 0; j <= i; j++) {
                if (mapInfo[mapInfo.length-1-i+j][j] == ps) {
                    num++;
                    succArr.push({
                        x:mapInfo.length-1-i+j,
                        y:j
                    })
                } else {
                    num = 0;
                    succArr = []
                }
                if (num == numCount) {
                    return succArr
                }
            }

        }
        //失败
        return false;
    }

    //是否五次出现
    fiveConsecutive(mapInfo, ps) {
        return this.isConsecutive(mapInfo, ps, 5);
    }

    //返回1或者2或者0
    situation(mapInfo) {

        if (this.fiveConsecutive(mapInfo, 1)) {
            return 1;
        }
        if (this.fiveConsecutive(mapInfo, 2)) {
            return 2;
        }
        return 0;
    }


    //检查是否下满
    isAll(mapInfo) {
        for (let i = 0; i < mapInfo.length; i++) {
            for (let j = 0; j < mapInfo[i].length; j++) {
                if (mapInfo[i][j] == 0) {
                    return false;
                }
            }
        }
        return true;
    }
    //随机下
    ranXia(mapInfo) {
        let y = Math.round(Math.random() * mapInfo.length);
        let x = Math.round(Math.random() * mapInfo.length);
        try {
            if (mapInfo[x][y] != 0) {
                return this.ranXia(mapInfo);
            }
        } catch (err) {
            console.log("在检查随机位置冲突时发生了异常");
            return this.ranXia(mapInfo);
        }
        return { x, y }
    }
    //堵子
    duXia(mapInfo) {

        //为自己成龙
        let me4 = this.duXia1(mapInfo,1,4);
        if (me4) {
            return me4;
        }

        //阻止对面成龙
        let enemy4 = this.duXia1(mapInfo,2,4);
        if (enemy4) {
            return enemy4;
        }
        //我已经有3个了
        let me3 = this.duXia1(mapInfo,1,3);
        if (me3) {
            return me3;
        }
        //阻止你的3个
        let enemy3 = this.duXia1(mapInfo,2,3);
        if (enemy3) {
            return enemy3;
        }
        //阻止你的两个
        let enemy2 = this.duXia1(mapInfo,2,2);
        if (enemy3) {
            return enemy3;
        }

        
        //填我的两个
        let me2 = this.duXia1(mapInfo,1,2);
        if (me2) {
            return me2;        
        }

        //填我的1个
        let me1 = this.duXia1(mapInfo,1,1);
        if (me1) {
            return me1;        
        }

        return false;

        
    }
    duXia1(mapInfo,who,num){
        let repices = this.isConsecutive(mapInfo, who, num);
        if(repices) console.log(`发现${who}-的子有-${num}连续`,repices);
        //堵第一个子
        let re = this.duXia2(mapInfo, repices[0],who)
        if (re) {
            //找到堵口
            console.log("堵了第一个子");
            return re;
        }
        //堵第最后1个子
        let rel = this.duXia2(mapInfo, repices[repices.length-1],who)
        if (rel) {
            //找到堵口
            console.log("堵了最后一个子");
            return rel;
        }
        if(repices) console.log("没堵住");
        return false;
    }
    duXia2(mapInfo, cpices,who) {
        if (cpices) {
            //左边
            if (
                cpices.x - 1 >= 0 && 
                mapInfo.length > cpices.x + 1 && 
                mapInfo[cpices.x + 1][cpices.y] == who && 
                mapInfo[cpices.x - 1][cpices.y] == 0
                ) {
                return {
                    x: cpices.x - 1,
                    y: cpices.y
                }
            }
            //右边
            if (
                cpices.x - 1 >= 0 && 
                mapInfo.length > cpices.x + 1 && 
                mapInfo[cpices.x - 1][cpices.y] == who && 
                mapInfo[cpices.x + 1][cpices.y] == 0
                ) {
                return {
                    x: cpices.x + 1,
                    y: cpices.y
                }
            }
            //上边
            if (cpices.y - 1 >= 0 && 
                mapInfo[0].length > cpices.y + 1 && 
                mapInfo[cpices.x][cpices.y + 1] == who && 
                mapInfo[cpices.x][cpices.y - 1] == 0
                ) {
                return {
                    x: cpices.x,
                    y: cpices.y - 1
                }
            }
            //下边
            if (cpices.y - 1 >= 0 && 
                mapInfo[0].length > cpices.y + 1 && 
                mapInfo[cpices.x][cpices.y - 1] == who && 
                mapInfo[cpices.x][cpices.y + 1] == 0
                ) {
                return {
                    x: cpices.x,
                    y: cpices.y + 1
                }
            }

            //第一象限
            if (
                cpices.y - 1 >= 0 && 
                mapInfo[0].length > cpices.y + 1 &&
                cpices.x - 1 >= 0 && 
                mapInfo.length > cpices.x + 1 && 
                mapInfo[cpices.x-1][cpices.y - 1] == who && 
                mapInfo[cpices.x+1][cpices.y + 1] == 0
                ) {
                return {
                    x: cpices.x + 1,
                    y: cpices.y + 1
                }
            }

            //第二象限
            if (
                cpices.y - 1 >= 0 && 
                mapInfo.length > cpices.y + 1 &&
                cpices.x - 1 >= 0 && 
                mapInfo.length > cpices.x + 1 && 
                mapInfo[cpices.x+1][cpices.y + 1] == who && 
                mapInfo[cpices.x-1][cpices.y - 1] == 0
                ) {
                return {
                    x: cpices.x - 1,
                    y: cpices.y - 1
                }
            }

            //第三象限
            if (
                cpices.y - 1 >= 0 && 
                mapInfo.length > cpices.y + 1 &&
                cpices.x - 1 >= 0 && 
                mapInfo.length > cpices.x + 1 && 
                mapInfo[cpices.x+1][cpices.y - 1] == who && 
                mapInfo[cpices.x-1][cpices.y + 1] == 0
                ) {
                return {
                    x: cpices.x - 1,
                    y: cpices.y + 1
                }
            }
            //第四象限
            if (
                cpices.y - 1 >= 0 && 
                mapInfo.length > cpices.y + 1 &&
                cpices.x - 1 >= 0 && 
                mapInfo.length > cpices.x + 1 && 
                mapInfo[cpices.x-1][cpices.y + 1] == who && 
                mapInfo[cpices.x+1][cpices.y - 1] == 0
                ) {
                return {
                    x: cpices.x + 1,
                    y: cpices.y - 1
                }
            }

        }
        return false;
    }

    xia(mapInfo) {
        if (this.isAll(mapInfo)) {
            return false;
        }

        //堵子
        let du = this.duXia(mapInfo)
        if (du) {
            return du;
        }

        console.log("开始随机下");

        //随机下
        return this.ranXia(mapInfo);
    }
    getBestPosition(board) {
        let maxScore = -1;
        let bestPosition = false;
        const boardSize = board.length;
      
        // 遍历棋盘上所有空位
        for (let i = 0; i < boardSize; i++) {
          for (let j = 0; j < boardSize; j++) {
            if (board[i][j] !== 0) {
              continue;
            }
      
            // 计算当前空位的得分
            const score = this.calculateScore(board, i, j, 1) + this.calculateScore(board, i, j, 2);
      
            // 如果得分比之前的最高分更高，则更新最高分和最佳位置
            if (score > maxScore) {
              maxScore = score;
              bestPosition = { x: i, y: j };
            }
          }
        }
      
        return bestPosition;
      }
      
      // 计算在指定位置下指定颜色的棋子所能获得的得分
    calculateScore(board, x, y, color) {
        let score = 0;
        const boardSize = board.length;
      
        // 水平方向
        let count = 0;
        for (let i = x - 4; i <= x + 4; i++) {
          if (i < 0 || i >= boardSize) {
            continue;
          }
          if (board[i][y] === color) {
            count++;
            if (count === 5) {
              score += 100000;
              break;
            }
          } else {
            if (count > 0) {
              score += this.calculateScoreByCount(count);
              count = 0;
            }
          }
        }
        if (count > 0) {
          score += this.calculateScoreByCount(count);
        }
      
        // 垂直方向
        count = 0;
        for (let j = y - 4; j <= y + 4; j++) {
          if (j < 0 || j >= boardSize) {
            continue;
          }
          if (board[x][j] === color) {
            count++;
            if (count === 5) {
              score += 100000;
              break;
            }
          } else {
            if (count > 0) {
              score += this.calculateScoreByCount(count);
              count = 0;
            }
          }
        }
        if (count > 0) {
          score += this.calculateScoreByCount(count);
        }
      
        // 左上到右下方向
        count = 0;
        for (let i = x - 4, j = y - 4; i <= x + 4; i++, j++) {
          if (i < 0 || i >= boardSize || j < 0 || j >= boardSize) {
            continue;
          }
          if (board[i][j] === color) {
            count++;
            if (count === 5) {
              score += 100000;
              break;
            }
          } else {
            if (count > 0) {
              score += this.calculateScoreByCount(count);
              count = 0;
            }
          }
        }
        if (count > 0) {
          score += this.calculateScoreByCount(count);
        }
      
        // 左下到右上方向
        count = 0;
        for (let i = x - 4, j = y + 4; i <= x + 4; i++, j--) {
          if (i < 0 || i >= boardSize || j < 0 || j >= boardSize) {
            continue;
          }
          if (board[i][j] === color) {
            count++;
            if (count === 5) {
              score += 100000;
              break;
            }
          } else {
            if (count > 0) {
              score += this.calculateScoreByCount(count);
              count = 0;
            }
          }
        }
        if (count > 0) {
          score += this.calculateScoreByCount(count);
        }
      
        return score;
      }
      
      // 根据棋子数量计算得分
    calculateScoreByCount(count) {
        switch (count) {
          case 1:
            return 1;
          case 2:
            return 10;
          case 3:
            return 100;
          case 4:
            return 1000;
          default:
            return 0;
        }
      }
}

let suan = new Suan();
export default suan